<!--
 * @Description: 按钮
 * @Author: James324
 * @Date: 2023-09-11 15:35:39
 * @LastEditors: James324
 * @LastEditTime: 2023-11-22 15:17:24
-->

<script lang="ts">
import { createVNode, SetupContext } from 'vue';
import { ElButton } from 'element-plus';
import QLoading from '@/components/q-loading/index.vue';

export default {
    inheritAttrs: false,
    props: {
        type: {
            type: String,
            default: 'default'
        },
        loading: {
            type: Boolean,
            default: false
        },
        buttonProps: {
            type: Object,
            default: () => ({})
        },
        actionFn: {
            type: Function
        },
        close: {
            type: Function,
            default: () => {}
        }
    },
    setup(props, { slots }: SetupContext) {
        const loading = ref(false);
        /**
         * 取消
         */
        const onInternalClose = () => {
            props.close?.();
        };

        function isThenable<T>(thing?: PromiseLike<T>): boolean {
            return !!(thing && thing.then);
        }

        const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
            if (!isThenable(returnValueOfOnOk)) {
                return;
            }

            loading.value = true;
            returnValueOfOnOk!.then(
                () => {
                    loading.value = false;
                    onInternalClose();
                },
                (e: Error) => {
                    loading.value = false;
                    return Promise.reject(e);
                }
            );
        };

        const onClick = () => {
            const { actionFn } = props;

            if (!actionFn) {
                onInternalClose();
            } else {
                if (typeof actionFn !== 'function') return;

                let returnValueOfOnOk: PromiseLike<any>;
                if (actionFn.length) {
                    // 传入 close 函数让权给调用者控制
                    returnValueOfOnOk = actionFn(close);
                } else {
                    // 返回 Promise 处理
                    returnValueOfOnOk = actionFn();
                    if (!returnValueOfOnOk) {
                        onInternalClose();
                        return;
                    }
                }
                handlePromiseOnOk(returnValueOfOnOk);
            }
        };

        return () =>
            createVNode(
                ElButton,
                {
                    size: 'default',
                    loading: loading.value,
                    type: props.type,
                    onClick,
                    ...props.buttonProps
                },
                {
                    ...slots,
                    loading: () => createVNode(QLoading)
                }
            );
    }
};
</script>
